#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: bingweichen
@contact: bingwei.chen11@gmail.com
@File    : __init__.py
@Time    : 2020/9/18 7:52 PM
@Site    :
@Software: IntelliJ IDEA
@desc:
"""

import decimal
import json
import time

from flask import Flask, Blueprint
from flask import current_app, make_response
from flask_records import FlaskRecords
from flask_cors import CORS
from flask_restplus import Api
from json import dumps

# import all dto here
from app.user.controller import api as user_ns
from app.user.auth_controller import api as auth_ns
from app.user.role_controller import api as role_ns

from app.customer.controller import api as customer_ns
from app.finance.account.controller import api as account_ns
from app.finance.account_flow.controller import api as account_flow_ns
from app.storage.storage_flow.controller import api as storage_flow_ns
from app.storage.storage_record.controller import api as storage_record_ns
from app.storage.warehouse.controller import api as warehouse_ns

# product
from app.product.sku.controller import api as sku_ns
from app.product.category.controller import api as category_ns
from app.product.spu.controller import api as spu_ns
from app.product.attribute.controller import api as attr_ns
from app.product.specification.controller import api as spec_ns
from app.product.unit.controller import api as unit_ns
from app.product.brand.controller import api as brand_ns

from app.coin.controller import api as coin_ns
from app.coupon.controller import api as coupon_ns
from app.file.controller import api as file_ns

# order
from app.order.purchase.controller import api as purchase_order_ns
from app.order.sale.controller import api as sale_order_ns
from app.order.check.controller import api as check_order_ns
from app.order.transfer.controller import api as transfer_order_ns
from app.order.purchase_return.controller import api as purchase_return_order_ns

from config import config
from exts import db

blueprint = Blueprint('api', __name__)

AUTHORIZATIONS = {
    "Authorization": {
        'type': 'apiKey',
        'in': 'header',
        'name': 'Authorization'
    }
}

api = Api(
    blueprint, title='RestPlus API Server', version='0.5.1 8月31日',
    description='a boilerplate for flask restplus web service', prefix='/api',
    # authorizations=AUTHORIZATIONS,
    # security=list(AUTHORIZATIONS.keys())
)
api.add_namespace(auth_ns, path='/auth')
api.add_namespace(user_ns, path='/user')
api.add_namespace(role_ns, path='/role')

# product
api.add_namespace(spu_ns, path='/spu')
api.add_namespace(unit_ns, path='/unit')
api.add_namespace(spec_ns, path='/spec')
api.add_namespace(attr_ns, path='/attr')
api.add_namespace(sku_ns, path='/sku')
api.add_namespace(category_ns, path='/category')

api.add_namespace(customer_ns, path='/customer')
api.add_namespace(account_ns, path='/account')
api.add_namespace(account_flow_ns, path='/account_flow')
api.add_namespace(storage_flow_ns, path='/storage_flow')
api.add_namespace(storage_record_ns, path='/storage_record')
api.add_namespace(warehouse_ns, path='/warehouse')
api.add_namespace(coin_ns, path='/coin')
api.add_namespace(coupon_ns, path='/coupon')
api.add_namespace(brand_ns, path='/brand')
api.add_namespace(file_ns, path='/file')
api.add_namespace(purchase_order_ns, path='/purchase_order')
api.add_namespace(sale_order_ns, path='/sale_order')
api.add_namespace(check_order_ns, path='/check_order')
api.add_namespace(transfer_order_ns, path='/transfer_order')
api.add_namespace(purchase_return_order_ns, path='/purchase_return_order')


# 配置 json encoder for decimal type
@api.representation('application/json')  # 指定响应形式对应的转换函数
def output_json(data, code, headers=None):
    """自定义json形式 https://blog.csdn.net/li944254211/article/details/109366048"""

    class DecimalEncoder(json.JSONEncoder):
        def default(self, o):
            if isinstance(o, decimal.Decimal):
                return float(o)
            super(DecimalEncoder, self).default(o)

    # 根据flask内置配置, 进行格式处理(缩进/key是否排序等)
    settings = current_app.config.get('RESTFUL_JSON', {})

    # 字典转json字符串
    dumped = dumps(data, **settings, cls=DecimalEncoder) + "\n"

    # 构建响应对象
    resp = make_response(dumped, code)
    resp.headers.extend(headers or {})
    return resp


def create_app(config_name):

    app = Flask(__name__)

    @app.after_request
    def after_request(response):
        # time.sleep(1)
        return response

    app.config.from_object(config[config_name])
    config[config_name].init_app(app)

    db.init_app(app)
    FlaskRecords(app)
    CORS(app, supports_credentials=True)
    app.register_blueprint(blueprint)

    return app
